package com.bbs.utils;

import org.apache.commons.lang.StringUtils;

import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;

public class Common {


    /**
     * 以2的次方开始的转换成整型数组，字符串数组
     * @param sum
     * @return
     */
    private static List<String> toUgroupArray(int sum){
        if(sum < 0){
            return null;
        }else if(sum == 0) {
            return null;
        }else{
            String binaryCode = Integer.toBinaryString(sum);//转换二进制编码字符串
            int index = binaryCode.length() -1;
            String str = "";
            for(int i=0;i<binaryCode.length();i++){
                if(binaryCode.charAt(i) == '1'){
                    str = str + index +",";
                }
                index --;
            }
            return Arrays.asList( str.split(","));
        }
    }

    /**
     * 数组去重
     * @param arr
     * @return
     */
    public static List<String> arr(List<Integer> arr){
        List<String> strArr = new ArrayList<>();
        for (Integer s : arr){
            List<String> newArr = toUgroupArray(s);
            strArr.addAll(newArr);
        }
        HashSet h = new HashSet(strArr);//
        strArr.clear();
        strArr.addAll(h);
        return strArr;
    }


    public static Date convertStringToDate(String dateString, String dateFormat) {
        Date date = null;
        DateFormat dateFormat1 = new SimpleDateFormat(dateFormat);
        try {
            date = dateFormat1.parse(dateString);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return date;
    }

    /**
     * 格式化时间格式
     *
     * @param srcDate
     * @return
     */
    public static Date formatDate(Date srcDate) {
        Date date = null;
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        String dateStr = sdf.format(srcDate) + " 00:00:00";
        try {
            date = sdf.parse(dateStr);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return date;
    }

    /**
     * 格式化时间格式
     *
     * @param srcDate
     * @return
     */
    public static Date formatDateCustomize(Date srcDate, String format) {
        if(StringUtils.isBlank(format)){
            format = "yyyy-MM-dd";
        }
        Date date = null;
        SimpleDateFormat sdf = new SimpleDateFormat(format);
        String dateStr = sdf.format(srcDate);
        try {
            date = sdf.parse(dateStr);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return date;
    }



    /**
     * 根据起始时间和结束时间获取范围内时间间隔 //TODO
     * 复制报价审核通过时，根据报价有效区间生成相应日期的板组；
     * 修改实际板组或托单手动审核通过时需生成当天开始，往后20天的板组
     *
     * @param dBegin
     * @param dEnd
     * @return
     */
    public static List<Date> getDatesRange(Date dBegin, Date dEnd) {
        {
            List lDate = new ArrayList();
            lDate.add(Common.formatDate(dBegin));
            Calendar calBegin = Calendar.getInstance();
            calBegin.setTime(dBegin);
            Calendar calEnd = Calendar.getInstance();
            calEnd.setTime(dEnd);
            while (dEnd.after(calBegin.getTime())) {
                calBegin.add(Calendar.DAY_OF_MONTH, 1);
                lDate.add(Common.formatDate(calBegin.getTime()));
            }
            return lDate;
        }
    }

    /**
     * 获取 差值 N 天
     * @param date
     * @param displacement
     * @return
     */
    public static Date getDisplacementDate(Date date, int displacement) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(Calendar.DAY_OF_MONTH, displacement);
        return calendar.getTime();
    }

    /**
     * 获取当前日期的周
     * 0 周日 1 ...
     * @param date
     * @return
     */
    public static int getWeekByDay(Date date){
        int week_index = -1;
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        week_index = cal.get(Calendar.DAY_OF_WEEK) - 1;

        return week_index;
    }

    /**
     * 根据起始日期返回 往后 range 天的日期列表
     * @param beginDate
     * @param range
     * @return
     */
    public static List<Date> getDateRangeFromDate(Date beginDate, int range){
        List<Date> resultList = new ArrayList<>();
        for(int i = 0;i<range;i++){
            Date date = new Date();
            Calendar calendar = Calendar.getInstance();
            calendar.setTime(beginDate);
            calendar.add(Calendar.DAY_OF_MONTH, i);
            date = calendar.getTime();
            resultList.add(date);
        }
        return resultList;
    }


    /**
     * 日期转星期
     *
     * @param datetime
     * @return
     */
    public static String dateToWeek(Date datetime) {
        SimpleDateFormat f = new SimpleDateFormat("yyyy-MM-dd");
        String[] weekDays = { "7", "1", "2", "3", "4", "5", "6" };
        Calendar cal = Calendar.getInstance(); // 获得一个日历
        Date datet = null;
        datet = datetime;
        cal.setTime(datet);
        int w = cal.get(Calendar.DAY_OF_WEEK) - 1; // 指示一个星期中的某天。
        if (w < 0)
            w = 0;
        return weekDays[w];
    }

    /**
     * 判断两个时间相差的毫秒数
     * @param srcDate
     * @param endDate
     * @return
     */
    public static long getTimeStmap(Date srcDate, Date endDate) {
        if (srcDate == null || endDate == null) {
            return 0;
        }

        return endDate.getTime() - srcDate.getTime();
    }


    public static Date getThisWeekMonday(Date date) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        // 获得当前日期是一个星期的第几天
        int dayWeek = cal.get(Calendar.DAY_OF_WEEK);
        if (1 == dayWeek) {
            cal.add(Calendar.DAY_OF_MONTH, -1);
        }
        // 设置一个星期的第一天，按中国的习惯一个星期的第一天是星期一
        cal.setFirstDayOfWeek(Calendar.MONDAY);
        // 获得当前日期是一个星期的第几天
        int day = cal.get(Calendar.DAY_OF_WEEK);
        // 根据日历的规则，给当前日期减去星期几与一个星期第一天的差值
        cal.add(Calendar.DATE, cal.getFirstDayOfWeek() - day);
        return cal.getTime();
    }

    //获取下周的周日日期
    public static Date getNextWeekSunday(Date date) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(getThisWeekMonday(date));
        cal.add(Calendar.DATE, 13);
        return cal.getTime();
    }

    /**
     * 获得该月最后一天
     * @param year
     * @param month
     * @return
     */
    public static String getLastDayOfMonth(int year,int month){
        Calendar cal = Calendar.getInstance();
        //设置年份
        cal.set(Calendar.YEAR,year);
        //设置月份
        cal.set(Calendar.MONTH, month-1);
        //获取某月最大天数
        int lastDay = cal.getActualMaximum(Calendar.DAY_OF_MONTH);
        //设置日历中月份的最大天数
        cal.set(Calendar.DAY_OF_MONTH, lastDay);
        //格式化日期
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        String lastDayOfMonth = sdf.format(cal.getTime());
        return lastDayOfMonth;
    }

    /**
     * 获得该月第一天
     * @param year
     * @param month
     * @return
     */
    public static String getFirstDayOfMonth(int year,int month){
        Calendar cal = Calendar.getInstance();
        //设置年份
        cal.set(Calendar.YEAR,year);
        //设置月份
        cal.set(Calendar.MONTH, month-1);
        //获取某月最小天数
        int firstDay = cal.getActualMinimum(Calendar.DAY_OF_MONTH);
        //设置日历中月份的最小天数
        cal.set(Calendar.DAY_OF_MONTH, firstDay);
        //格式化日期
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        String firstDayOfMonth = sdf.format(cal.getTime());
        return firstDayOfMonth;
    }

    /**
     * 获取几个月前的开始日期
     * @param date
     * @param number 获取number个月前的时间
     * @param type 0:获取最后一天，1：获取第一天
     * @return
     */
    public static Date getNextWeekSunday(Date date,int number,int type) {
        Calendar cal = Calendar.getInstance();
        Integer year = cal.get(cal.YEAR);//获取当前年
        int month = cal.get(cal.MONTH)+1;//获取当前月
        month -= number;
        String strDate = "";
        if (type == 0){
            strDate = getLastDayOfMonth(year,month);
        } else {
            strDate = getFirstDayOfMonth(year,month);
        }

        return convertStringToDate(strDate,"yyyy-MM-dd");
    }

    /**
     * 获取指定日期位于当月的周
     * @param date
     * @return
     */
    public static int getWeekOfMonth(Date date){
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        int weekOfMonth = calendar.get(Calendar.WEEK_OF_MONTH);
        return  weekOfMonth;
    }

    /**
     * 获取指定日期的月
     * @param date
     * @return
     */
    public static int getMonth(Date date){
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        int month = calendar.get(Calendar.MONTH)+1;
        return  month;
    }

    /**
     * 根据当前日期获取前N个月的日期
     * @return
     */
    public static Date getDate(Date date,int month){
        Calendar cal=Calendar.getInstance();
        cal.setTime(date);
        cal.add(Calendar.MONTH,-month);//对月份进行计算,减去12个月
        Date newDate=cal.getTime();
        return newDate;
    }

    /**
     * 判断指定时间是否在一个时间段内
     * @return
     */

    public static boolean getDateInterval(Date date1,Date date2,Date date3 ){
        Calendar date = Calendar.getInstance();
        date.setTime(date3);

        Calendar begin = Calendar.getInstance();
        begin.setTime(date1);

        Calendar end = Calendar.getInstance();
        end.setTime(date2);

        if (date.compareTo(begin) > -1 && date.compareTo(end) < 1) {
            return true;
        } else {
            return false;
        }
    }

    public static final Date convertStringToDate(String strDate){
        SimpleDateFormat df = null;
        Date date = null;
        df = new SimpleDateFormat("yyyy-MM-dd");
        try {
            date = df.parse(strDate);
        } catch (ParseException pe) {
            pe.printStackTrace();
        }
        return (date);
    }

    public static Calendar getCalendar(String month, int week) {
        try {
            Date newDate = convertStringToDate(month + "-01");
            Calendar caleNew = Calendar.getInstance();
            caleNew.setTime(newDate);
            caleNew.add(Calendar.WEEK_OF_MONTH, week -1 );
            return caleNew;
        } catch (Exception e){
            e.printStackTrace();
        }
        return null;
    }


    /**
     * 数组去重
     * @param arr
     * @return
     */
    public static List<String> arrToHeavy(List<Integer> arr){
        List<String> strArr = new ArrayList<>();
        for (Integer s : arr){
            if (s != null && s > 0){
                List<String> newArr = toUgroupArray(s);
                strArr.addAll(newArr);
            }
        }
        HashSet h = new HashSet(strArr);//
        strArr.clear();
        strArr.addAll(h);
        return strArr;
    }

    /**
     * 字符串md5加密
     * @param buf
     * @return
     */
    public static String EncoderByMd5(String buf) {
        try {
            // 得到一个信息摘要器
            MessageDigest digest = MessageDigest.getInstance("md5");
            byte[] result = digest.digest(buf.getBytes());
            StringBuffer buffer = new StringBuffer();
            // 把每一个byte 做一个与运算 0xff;
            for (byte b : result) {
                // 与运算
                int number = b & 0xff;// 加盐
                String str = Integer.toHexString(number);
                if (str.length() == 1) {
                    buffer.append("0");
                }
                buffer.append(str);
            }

            // 标准的md5加密后的结果
            return buffer.toString();
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
            return "";
        }
    }


}
